package com.sdy.supermarket.biz.service.impl;

import com.baomidou.mybatisplus.core.conditions.Condition;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.additional.query.impl.LambdaQueryChainWrapper;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.sdy.approval.api.ApprovalAllApi;
import com.sdy.approval.biz.model.TpApproveFlowConfig;
import com.sdy.common.model.BizException;
import com.sdy.common.model.FileObj;
import com.sdy.common.model.Response;
import com.sdy.common.utils.Assert;
import com.sdy.common.utils.MapUtil;
import com.sdy.common.utils.StringUtil;
import com.sdy.fs.api.FsApi;
import com.sdy.mvc.utils.JsonUtil;
import com.sdy.supermarket.biz.mapper.GsResMapper;
import com.sdy.supermarket.biz.model.GsCategoryManage;
import com.sdy.supermarket.biz.model.GsOrderItem;
import com.sdy.supermarket.biz.model.GsRes;
import com.sdy.supermarket.biz.model.GsResDoc;
import com.sdy.supermarket.biz.service.GsCategoryManageService;
import com.sdy.supermarket.biz.service.GsOrderItemService;
import com.sdy.supermarket.biz.service.GsResDocService;
import com.sdy.supermarket.biz.service.GsResService;
import com.sdy.mvc.service.impl.BaseServiceImpl;
import com.sdy.supermarket.biz.vo.ApprovalConfigObj;
import com.sdy.supermarket.biz.vo.ResIntroVO;
import com.sdy.supermarket.biz.vo.ResSimpleVO;
import com.sdy.usercenter.api.UserQueryApi;
import com.sdy.usercenter.api.dto.DeptDto;
import com.sdy.usercenter.api.dto.RoleDto;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 资源表 服务实现类
 * </p>
 *
 * @author zzq
 * @since 2019-07-31
 */
@Slf4j
@Service
public class GsResServiceImpl extends BaseServiceImpl<GsRes> implements GsResService {
    @Resource
    private GsResMapper gsResMapper;
    @Autowired
    private GsCategoryManageService gsCategoryManageService;
    @Autowired
    private GsResDocService gsResDocService;
    @Autowired
    private ApprovalAllApi approvalAllApi;
    @Autowired
    private UserQueryApi userQueryApi;
    @Autowired
    private GsOrderItemService gsOrderItemService;
    @Autowired
    private FsApi fsApi;

    @Override
    public List<GsRes> listRes(Integer category, Integer type) {
        List<GsCategoryManage> catList = gsCategoryManageService.lambdaQuery().eq(GsCategoryManage::getPid, category).list();
        LambdaQueryWrapper<GsRes> wrapper = new LambdaQueryWrapper<>();
        catList.add(new GsCategoryManage().setId(-1));
        wrapper.in(category != null, GsRes::getCategory, catList.stream().map(GsCategoryManage::getId).collect(Collectors.toList()))
                .eq(type != null, GsRes::getType, type)
                .eq(GsRes::getState, 1)
                .orderByDesc(GsRes::getId);
        return list(wrapper);
    }

    @Override
    public List<GsRes> queryHotResList() {
        LambdaQueryWrapper<GsRes> query = new LambdaQueryWrapper<>();
        query.eq(GsRes::getPopular, 1).last(" limit 8");
        List<GsRes> gsRes = gsResMapper.selectList(query);
        return gsRes;
    }

    @Override
    public List<GsRes> get7DaysList() {
        return gsResMapper.get7DaysList();
    }


    @Override
    public void createRes(GsRes res) throws Exception {
        res.setIntroduction(JsonUtil.toJson(res.getResIntroVO()));
        res.setCreateTime(new Date());
        save(res);
        // 资源文档
        if (res.getDocList() != null) {
            res.getDocList().forEach(doc -> {
                gsResDocService.save(new GsResDoc()
                        .setFileUrl(doc.getFileUrl())
                        .setResId(res.getId())
                        .setName(doc.getName())
                        .setCreateTime(new Date()));
            });
        }
        Assert.isTrue(res.getApprovalConfigObj() == null || CollectionUtils.isEmpty(res.getApprovalConfigObj().getItemList()),
                "审批流程不能为空");
        String r = approvalAllApi.insertApproval(
                res.getApprovalConfigObj().getItemList().stream().map(ApprovalConfigObj.ApprovalConfigItem::getDeptId).collect(Collectors.toList()),
                res.getApprovalConfigObj().getItemList().stream().map(ApprovalConfigObj.ApprovalConfigItem::getRoleId).collect(Collectors.toList()),
                "政务超市",
                res.getId()+"");
        Assert.isTrue(!"流程生成成功".equals(r), "资源审批流程创建失败，原因：" + r);
    }

    @Override
    public void updateRes(GsRes res) throws Exception {
        res.setIntroduction(JsonUtil.toJson(res.getResIntroVO()));
        res.setCreateTime(null);
        updateById(res);
        // 更新流程节点
        String r = approvalAllApi.insertApproval(
                res.getApprovalConfigObj().getItemList().stream().map(ApprovalConfigObj.ApprovalConfigItem::getDeptId).collect(Collectors.toList()),
                res.getApprovalConfigObj().getItemList().stream().map(ApprovalConfigObj.ApprovalConfigItem::getRoleId).collect(Collectors.toList()),
                "政务超市",
                res.getId()+"");
        Assert.isTrue(!"流程生成成功".equals(r), "资源审批流程修改失败，原因：" + r);
        // 更新资源文档
        if (res.getDocList() != null) {
            List<GsResDoc> resDocList = gsResDocService.list(
                    new LambdaQueryWrapper<GsResDoc>().eq(GsResDoc::getResId, res.getId())
            );
            List<GsResDoc> toAddList = res.getDocList()
                    .stream()
                    .filter(doc -> doc.getId() == null)
                    .collect(Collectors.toList());
            List<Integer> toDelList = resDocList
                    .stream()
                    .map(GsResDoc::getId)
                    .filter(docId -> !res.getDocList()
                            .stream()
                            .filter(item -> item.getId() != null)
                            .map(GsResDoc::getId)
                            .collect(Collectors.toList()).contains(docId))
                    .collect(Collectors.toList());
            if (!toDelList.isEmpty()) {
                gsResDocService.removeByIds(toDelList);
            }
            toAddList.forEach(doc -> {
                gsResDocService.save(new GsResDoc()
                        .setFileUrl(doc.getFileUrl())
                        .setResId(res.getId())
                        .setName(doc.getName())
                        .setCreateTime(new Date()));
            });
        }
    }

    @Override
    public IPage<ResSimpleVO> pageRes(Page<GsRes> page) {
        IPage<GsRes> p = page(page);
        IPage<ResSimpleVO> resSimpleVOIPage = JsonUtil.convertPage(p, ResSimpleVO.class);
        // 获取分类
        if (!resSimpleVOIPage.getRecords().isEmpty()) {
            Collection<GsCategoryManage> categoryList = gsCategoryManageService.listByIds(resSimpleVOIPage.getRecords()
                    .stream()
                    .map(ResSimpleVO::getCategory)
                    .collect(Collectors.toList()));
            Map<Integer, GsCategoryManage> categoryMap = MapUtil.collectionToMap(categoryList, GsCategoryManage::getId);
            resSimpleVOIPage.getRecords().forEach(item -> {
                GsCategoryManage categoryManage = categoryMap.get(item.getCategory());
                if (categoryManage != null) {
                    item.setCategoryStr(categoryManage.getCategoryName());
                }
            });
        }
        return resSimpleVOIPage;
    }

    @Override
    public GsRes getRes(Integer resId) throws BizException {
        GsRes res = getById(resId);
        Assert.isNull(res, "资源不存在！");
        List<GsResDoc> docList = gsResDocService.list(
                new LambdaQueryWrapper<GsResDoc>().eq(GsResDoc::getResId, res.getId())
        );
        // 拿到所有的模块文件id
        StringBuilder fileId = new StringBuilder();
        docList.forEach(doc -> {
            fileId.append(doc.getFileUrl());
        });
        // 查询后将对应的文件放入其列表中
        if (StringUtil.isNotBlank(new String(fileId)) && StringUtil.isNotEmpty(new String(fileId))) {
            List<FileObj> fileListInfo = fsApi.getFileListInfo(Arrays.asList(new String(fileId).split(",")));
            for (GsResDoc doc : docList) {
                for (FileObj fileObj : fileListInfo) {
                    if (doc.getFileUrl().indexOf(fileObj.getId()) != -1) {
                        doc.getFileObjList().add(fileObj);
                        doc.getFileUrl().replace(fileObj.getId(), "");
                    }
                }
            }
        }
        if (res.getIcon() != null && StringUtil.isNotBlank(res.getIcon())) {
            res.setIconInfo(fsApi.getFileInfo(res.getIcon()));
        }
        if (res.getBanner() != null && StringUtil.isNotBlank(res.getBanner())) {
            res.setBannerInfo(fsApi.getFileListInfo(Arrays.asList(res.getBanner().split(","))));
        }
        res.setDocList(docList);
        ResIntroVO resIntroVO = JsonUtil.fromJson(res.getIntroduction(), ResIntroVO.class);
        List<FileObj> fileListInfo = fsApi.getFileListInfo(resIntroVO.getModuleList().stream().map(vo -> vo.getImgUrl()).collect(Collectors.toList()));
        for (ResIntroVO.ResIntroModule resint : resIntroVO.getModuleList()) {
            for (FileObj file : fileListInfo) {
                if (file.getId().equals(resint.getImgUrl())) {
                    resint.setFileInfo(file);
                }
            }
        }
        res.setResIntroVO(resIntroVO);
        res.setIntroduction(null);
        List<TpApproveFlowConfig> l = approvalAllApi.selectApprovalByResId("[政务超市]" + resId);
        List<DeptDto> deptDtoList = userQueryApi.listDeptByIds(l.stream().map(TpApproveFlowConfig::getAuditDepartmentId).collect(Collectors.toList()));
        List<RoleDto> roleDtoList = userQueryApi.listRoleByIds(l.stream().map(TpApproveFlowConfig::getAuditRoleId).collect(Collectors.toList()));
        Map<Integer, DeptDto> deptMap = MapUtil.collectionToMap(deptDtoList, DeptDto::getId);
        Map<Integer, RoleDto> roleMap = MapUtil.collectionToMap(roleDtoList, RoleDto::getId);
        res.setApprovalConfigObj(new ApprovalConfigObj().setItemList(
                l.stream().map(item -> {
                            DeptDto dept = deptMap.get(item.getAuditDepartmentId());
                            RoleDto role = roleMap.get(item.getAuditRoleId());
                            return new ApprovalConfigObj.ApprovalConfigItem()
                                    .setDeptId(item.getAuditDepartmentId())
                                    .setDeptName(dept == null ? "" : dept.getAbbreviation())
                                    .setRoleId(item.getAuditRoleId())
                                    .setRoleName(role == null ? "" : role.getName());
                        }
                ).collect(Collectors.toList())
        ));
        return res;
    }

    @Override
    public void putOnRes(Integer resId) {
        updateById(new GsRes().setState(1).setId(resId));
    }

    @Override
    public void putOffRes(Integer resId) {
        updateById(new GsRes().setState(2).setId(resId));
    }

    @Override
    public void removeRes(Integer resId) throws BizException {
        List<GsOrderItem> gsOrderItems = gsOrderItemService.list(Wrappers.<GsOrderItem>lambdaQuery().eq(GsOrderItem::getResId, resId));
        Assert.isTrue(!gsOrderItems.isEmpty(), "该资源还在使用，不可删除");
        Boolean aBoolean = approvalAllApi.deleteFlowConfig("[政务超市]", resId);
        boolean removeById = removeById(resId);
        Assert.isTrue(!aBoolean || !removeById, "该资源被占用,不可删除");
    }

}
